from rest_framework import status
from rest_framework.generics import GenericAPIView, CreateAPIView
from rest_framework.response import Response
from rest_framework.views import APIView

from oauth.exceptions import QQAPIError
from oauth.models import OAuthQQUser
from oauth.serializers import QQAuthUserSerializer
from oauth.utils import OAuthQQ

from users.models import User


# GET /oauth/qq/user/?code=xxx
class QQAuthUserView(CreateAPIView):
    serializer_class = QQAuthUserSerializer

    # def post(self, request):
    #     '''获取表单数据进行绑定'''
    #     # 创建序列化器对象
    #     serializer = self.get_serializer(data=request.data)
    #
    #     # 校验参数
    #     serializer.is_valid()
    #
    #     # 保存数据
    #     serializer.save()
    #
    #     # 返回响应
    #     return Response(serializer.data)

    def get(self, request):
        '''获取openid'''
        # 获取查询字符串中code
        code = request.query_params.get('code')

        # 根据code获取access_token
        auth_qq = OAuthQQ()
        try:
            access_token = auth_qq.get_access_token(code)

            # 根据access_token获取openid
            openid = auth_qq.get_openid(access_token)
        except QQAPIError as e:
            return Response({'message': 'QQ服务异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 判断openid是否与用户绑定
        try:
            qq_auth = OAuthQQUser.objects.get(openid=openid)

        except OAuthQQUser.DoesNotExist:
            # 如果没有获取到,用户没有绑定,返回加密的openid
            token = auth_qq.generate_save_user_token(openid)
            return Response({'access_token': token})
        else:
            # 如果已经绑定
            # 获取用户对象
            user = qq_auth.user
            # 创建对象时生成token
            from rest_framework_jwt.settings import api_settings
            # 生成载荷的方法
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            # 生成token的方法
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            # 生成载荷
            payload = jwt_payload_handler(user)
            # 生成token
            token = jwt_encode_handler(payload)

            # 给user添加token字段,将token返回给客户端
            user.token = token
            response_data = {
                'user_id': user.id,
                'username': user.username,
                'token': token
            }
            return Response(response_data)


# url : /oauth/qq/authorization/?next=xxx
class QQAuthURLView(APIView):
    '''获取QQ的登录网址'''

    def get(self, request):
        '''
        获取参数
        返回响应
        '''
        # 获取参数
        next = request.query_params.get('next', '/')

        # 创建QQ集成工具类的对象
        autho_qq = OAuthQQ(state=next)
        # 获取qq登录的网址
        login_url = autho_qq.get_login_url()
        # 返回响应
        return Response({'login_url': login_url})
